package jp.android_group.attender.android.entity;

/*
 * Copyright (c) 2009, "Japan Android Group Attender Team"
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Collection;
import java.util.LinkedList;

import jp.android_group.attender.android.util.TextUtils;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

/**
 * サーバーエントリのモデル
 * 
 * @author Keiji Ariyama <keiji_ariyama@c-lis.co.jp>
 * 
 */
public class ServerEntry implements Serializable {
	private static final String LOG_TAG = "ServerEntry";
	private static final boolean DEBUG_FLG = true;

	// 認証情報の保存ファイル名
	public static final String FILE_NAME = "login.dat";

	/**
	 * 
	 */
	private static final long serialVersionUID = -8220123535276062071L;

	private int id = -1;
	private boolean enableFlg = true;
	private String label = null;
	private String loginId = null;
	private String password = null;
	private String baseUrl = null;

	private int serverType = SERVER_TYPE_MAIMUZO_LEGACY;
	public static final int SERVER_TYPE_MAIMUZO_LEGACY = 0x0;
	public static final int SERVER_TYPE_MAIMUZO_GAE = 0x1;
	public static final int SERVER_TYPE_OTHERS = 0xFFFFFFFF;

	private int protocolType = PROTOCOL_TYPE_NOT_SET;
	public static final int PROTOCOL_TYPE_NOT_SET = 0xFFFFFFFF;
	public static final int PROTOCOL_TYPE_MAIMUZO = 0x1;
	public static final int PROTOCOL_TYPE_SOAP1 = 0x2;

	private long lastRetrieveDate = -1;

	/**
	 * 
	 * @param val
	 */
	public void setEnable(int val) {
		if (val == 1) {
			this.enableFlg = true;
		} else if (val == -1) {
			this.enableFlg = false;
		}
	}

	/**
	 * 
	 * @return
	 */
	public int getEnableInt() {
		if (enableFlg)
			return 1;
		return -1;
	}

	/**
	 * 
	 * @return
	 */
	public String getLastRetrieveDateStr() {
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(this.lastRetrieveDate);
		return TextUtils.cal2DateStr(cal);
	}

	/**
	 * 認証情報の保存
	 * 
	 * @param in
	 * @param data
	 * @throws IOException
	 */
	public static void save(FileOutputStream out, ServerEntry data)
			throws IOException {

		ObjectOutputStream objOut = new ObjectOutputStream(out);
		objOut.writeObject(data);
		objOut.flush();
		objOut.close();

	}

	/**
	 * 認証情報の読み込み
	 * 
	 * @param in
	 * @return
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	public static ServerEntry load(FileInputStream in) throws IOException,
			ClassNotFoundException {

		ServerEntry result = null;

		ObjectInputStream objIn = new ObjectInputStream(in);
		result = (ServerEntry) objIn.readObject();

		return result;
	}

	private static final String TABLE_NAME = "m_server_entry";
	private static final String[] projection = new String[] { "id",
			"enable_flg", "label", "base_url", "protocol_type", "login_id",
			"login_password", "last_retrieve_date" };

	/**
	 * イベントテーブルを作成
	 * 
	 * @param db
	 */
	public static void createTable(SQLiteDatabase db) {
		StringBuilder sql = new StringBuilder();
		sql.append("CREATE TABLE " + TABLE_NAME);
		sql.append(" (");
		sql.append("id INTEGER PRIMARY KEY, ");
		sql.append("enable_flg INTEGER, ");
		sql.append("label TEXT, ");
		sql.append("base_url TEXT, ");
		sql.append("server_type INTEGER, ");
		sql.append("protocol_type INTEGER, ");
		sql.append("login_id TEXT, ");
		sql.append("login_password TEXT, ");
		sql.append("last_retrieve_date TEXT ");
		sql.append(")");
		db.execSQL(sql.toString());
	}

	/**
	 * DBに保存
	 * 
	 * @param data
	 * @param db
	 */
	public static void save(ServerEntry data, SQLiteDatabase db) {
		ContentValues values = new ContentValues();
		values.put("label", data.getLabel());
		values.put("enable_flg", data.getEnableInt());
		values.put("base_url", data.getBaseUrl());
		values.put("server_type", data.getServerType());
		values.put("protocol_type", data.getProtocolType());
		values.put("login_id", data.getLoginId());
		values.put("login_password", data.getPassword());
		if (data.getLastRetrieveDate() > 0) {
			values.put("last_retrieve_date", data.getLastRetrieveDate());
		}

		boolean existFlg = false;
		Collection<ServerEntry> list = load(data.getLabel(), data.getBaseUrl(),
				db);
		if (list.size() > 0)
			existFlg = true;

		if (existFlg == false) {
			db.insert(TABLE_NAME, null, values);
		} else {
			db.update(TABLE_NAME, values, "label = ?", new String[] { data
					.getLabel() });
			if (DEBUG_FLG)
				Log.v(LOG_TAG, "insert is failed. target data is updated");
		}
	}

	/**
	 * DBを読込み
	 * 
	 * @param db
	 * @return
	 */
	public static Collection<ServerEntry> load(SQLiteDatabase db) {
		LinkedList<ServerEntry> list = new LinkedList<ServerEntry>();
		Cursor cursor = db.query(TABLE_NAME, projection, "id > ?",
				new String[] { "0" }, null, null, "id desc");

		if (cursor.moveToFirst()) {
			do {
				list.add(fetchData(cursor));
			} while (cursor.moveToNext());
		}

		cursor.close();

		return list;
	}

	/**
	 * DBを読込み
	 * 
	 * @param db
	 * @return
	 */
	public static ServerEntry load(int id, SQLiteDatabase db) {
		ServerEntry data = null;
		Cursor cursor = db.query(TABLE_NAME, projection, "id = ?",
				new String[] { String.valueOf(id) }, null, null, "id desc");

		if (cursor.moveToFirst()) {
			data = fetchData(cursor);
		}

		cursor.close();

		return data;
	}

	/**
	 * ＤＢを読込み
	 * 
	 * @param db
	 * @return
	 */
	public static Collection<ServerEntry> load(String label, String baseUrl,
			SQLiteDatabase db) {
		LinkedList<ServerEntry> list = new LinkedList<ServerEntry>();

		if (label == null)
			label = "%";
		if (baseUrl == null)
			baseUrl = "%";

		Cursor cursor = db.query(TABLE_NAME, projection, "label LIKE ?",
				new String[] { label }, null, null, "id desc");

		if (cursor.moveToFirst()) {
			do {
				list.add(fetchData(cursor));
			} while (cursor.moveToNext());
		}

		cursor.close();

		return list;
	}

	/**
	 * データのフェッチ
	 * 
	 * @param cursor
	 * @return
	 */
	private static ServerEntry fetchData(Cursor cursor) {
		ServerEntry data = new ServerEntry();
		data.setId(cursor.getInt(cursor.getColumnIndex("id")));
		data.setEnable(cursor.getInt(cursor.getColumnIndex("enable_flg")));
		data.setLabel(cursor.getString(cursor.getColumnIndex("label")));
		data.setBaseUrl(cursor.getString(cursor.getColumnIndex("base_url")));
		data.setProtocolType(cursor.getInt(cursor
				.getColumnIndex("protocol_type")));
		data.setLoginId(cursor.getString(cursor.getColumnIndex("login_id")));
		data.setLoginPassword(cursor.getString(cursor
				.getColumnIndex("login_password")));
		String lastRetrieveDate = cursor.getString(cursor
				.getColumnIndex("last_retrieve_date"));
		if (lastRetrieveDate != null)
			data.setLastRetrieveDate(Long.parseLong(lastRetrieveDate));
		return data;
	}

	/*
	 * setter and getter
	 */

	/**
	 * @param _Id
	 *            the _Id to set
	 */
	public void setId(int _Id) {
		this.id = _Id;
	}

	/**
	 * @return the _Id
	 */
	public int getId() {
		return id;
	}

	/**
	 * @param enableFlg
	 *            the enableFlg to set
	 */
	public void setEnableFlg(boolean enableFlg) {
		this.enableFlg = enableFlg;
	}

	/**
	 * @return the enableFlg
	 */
	public boolean isEnable() {
		return enableFlg;
	}

	/**
	 * @param label
	 *            the label to set
	 */
	public void setLabel(String label) {
		this.label = label;
	}

	/**
	 * @return the label
	 */
	public String getLabel() {
		return label;
	}

	/**
	 * @param label
	 *            the label to set
	 */
	public void setLoginId(String val) {
		this.loginId = val;
	}

	/**
	 * @return the label
	 */
	public String getLoginId() {
		return loginId;
	}

	/**
	 * @param _Password
	 *            the _Password to set
	 */
	public void setLoginPassword(String _Password) {
		this.password = _Password;
	}

	/**
	 * @return the _Password
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * @param baseUrl
	 *            the baseUrl to set
	 */
	public void setBaseUrl(String baseUrl) {
		this.baseUrl = baseUrl;
	}

	/**
	 * @return the baseUrl
	 */
	public String getBaseUrl() {
		return baseUrl;
	}

	/**
	 * @param serverType
	 *            the serverType to set
	 */
	public void setServerType(int serverType) {
		this.serverType = serverType;
	}

	/**
	 * @return the serverType
	 */
	public int getServerType() {
		return serverType;
	}

	/**
	 * @param _ProtocolType
	 *            the _ProtocolType to set
	 */
	public void setProtocolType(int _ProtocolType) {
		this.protocolType = _ProtocolType;
	}

	/**
	 * @return the _ProtocolType
	 */
	public int getProtocolType() {
		return protocolType;
	}

	/**
	 * @param lastRetrieveDate
	 *            the lastRetrieveDate to set
	 */
	public void setLastRetrieveDate(long lastRetrieveDate) {
		this.lastRetrieveDate = lastRetrieveDate;
	}

	/**
	 * @return the lastRetrieveDate
	 */
	public long getLastRetrieveDate() {
		return lastRetrieveDate;
	}

	/*
	 * setter and getter
	 */

}
